package com.warmheart.base.filter;

import java.io.IOException;
import java.util.Date;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.warmheart.base.config.SysConfig.Log;
import com.warmheart.base.executor.TraceContext;

/**
 * 
 * @ClassName: ParamLogFilter
 * @Description: 数据记录过滤器
 * @author ZhangJianyang
 * @date 2025-06-16 09:37:02
 *
 */
public abstract class ParamLogFilter implements Filter {

    private static Logger logger = LoggerFactory.getLogger(ParamLogFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        if (!log().getParam() && !log().getResult()) {
            chain.doFilter(request, response);
            return;
        }
        Date startTime = new Date();
        String preSpanId = TraceContext.getSpan();
        TraceContext.setSpan();
        logger.info("----------------------------数据记录处理开始----------------------------");
        HttpServletResponse hResponse = null;
        try {
            if (request instanceof HttpServletRequest) {
                HttpServletRequest hRequest = (HttpServletRequest) request;
                hResponse = (HttpServletResponse) response;
                // 这里只处理POST请求
                if (hRequest.getMethod().equalsIgnoreCase("post")) {
                    logger.info("请求方式：POST");
                    String contentType = hRequest.getContentType();
                    // 记录参数
                    logger.info("请求内容类型：" + contentType);
                    ParamLogRequestWrapper requestWrapper = null;
                    if (log().getParam()) {
                        if (StringUtils.isBlank(contentType) || !contentType.contains("multipart/form-data")) {
                            requestWrapper = new ParamLogRequestWrapper(hRequest);
                            if (StringUtils.isNotBlank(contentType)
                                    && contentType.contains("application/x-www-form-urlencoded")) {
                                String paramInfo = requestWrapper.getParamInfo();
                                logger.info("请求参数：" + paramInfo);
                            } else {
                                String bodyStr = requestWrapper.getRequestBody();
                                logger.info("请求参数：" + bodyStr);
                            }
                        }
                    }
                    if (log().getResult()) {
                        ParamLogResponseWrapper responseWrapper = new ParamLogResponseWrapper(hResponse);
                        if (log().getParam() && requestWrapper != null) {
                            chain.doFilter(requestWrapper, responseWrapper);
                        } else {
                            chain.doFilter(hRequest, responseWrapper);
                        }
                        // 写出数据，同时打印响应日志
                        responseWrapper.reWrite(logger);
                    } else {
                        if (log().getParam() && requestWrapper != null) {
                            chain.doFilter(requestWrapper, hResponse);
                        } else {
                            chain.doFilter(hRequest, hResponse);
                        }
                    }
                } else if (hRequest.getMethod().equalsIgnoreCase("get")) {
                    logger.info("请求方式：GET");
                    String contentType = hRequest.getContentType();
                    // 记录参数
                    logger.info("请求内容类型：" + contentType);
                    ParamLogRequestWrapper requestWrapper = null;
                    if (log().getParam()) {
                        requestWrapper = new ParamLogRequestWrapper(hRequest);
                        try {
                            String paramInfo = requestWrapper.getParamInfo();
                            logger.info("请求参数：" + paramInfo);
                        } catch (Exception e) {
                            logger.error("打印请求参数报错", e);
                        }
                    }
                    if (log().getResult()) {
                        ParamLogResponseWrapper responseWrapper = new ParamLogResponseWrapper(hResponse);
                        if (log().getParam()) {
                            chain.doFilter(requestWrapper, responseWrapper);
                        } else {
                            chain.doFilter(hRequest, responseWrapper);
                        }
                        // 写出数据，同时打印响应日志
                        responseWrapper.reWrite(logger);
                    } else {
                        if (log().getParam()) {
                            chain.doFilter(requestWrapper, hResponse);
                        } else {
                            chain.doFilter(hRequest, hResponse);
                        }
                    }
                } else {
                    chain.doFilter(hRequest, hResponse);
                }
            } else {
                chain.doFilter(request, response);
            }
        } catch (Exception e) {
            logger.error("数据记录过滤器处理失败：" + e.getMessage(), e);
        } finally {
            Long nextSpanCost = TraceContext.getSpanCost();
            Date endTime = new Date();
            Long currSpanCost = endTime.getTime() - startTime.getTime() - nextSpanCost;
            logger.info("数据记录处理耗时{}ms", currSpanCost);
            logger.info("----------------------------数据记录处理结束----------------------------");
            TraceContext.resetSpanCost(endTime.getTime() - startTime.getTime());
            TraceContext.resetSpan(preSpanId);
        }
    }

    /**
     * 
     * @Title: log
     * @Description: 打印参数配置
     * @author ZhangJianyang
     * @return
     */
    protected abstract Log log();
}
